/*
 * Copyright (C) 2011, EADS France
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */
package xowl.gmi.controller;

/**
 *
 * @author Laurent WOUTERS
 */
public abstract class Element {
    protected Controller controller;
    protected Element parent;
    
    public Element(Controller controller, Element parent) {
        this.controller = controller;
        this.parent = parent;
    }
    
    public abstract xowl.gmi.view.diagram.Widget getWidget();
    
    public Element getParent() { return parent; }
    
    protected ASTElement getASTParent() {
        if (parent == null)
            return null;
        return parent.getNearestAST();
    }
    protected ASTElement getNearestAST() { return parent.getNearestAST(); }    
    
    protected abstract int getContainedASTCount();                                      // Get the number of AST node contained by this element
    protected abstract int getLeftSiblingsASTCount(Element divider);                    // Get the number of AST sibling nodes on the left
    protected abstract boolean insertAST(xowl.gmi.model.ast.ASTNode node);              // Insert the given AST into the tree
    protected abstract ASTRemovalStatus removeAST(xowl.gmi.model.ast.ASTNode node);     // Remove the given AST from the tree
    
    public abstract void saveTo(xowl.gmi.model.Diagram diagram);                // Save this element to the diagram model
    public abstract void decommission();                                        // Decommission this subtree
    
    protected Integer getValueInteger(xowl.gmi.model.cvssl.ValueInteger value, xowl.interpreter.adapter.DataPropertyObserver obs) {
        if (value == null) return null;
        if (value instanceof xowl.gmi.model.cvssl.ConstantInteger)
            return ((xowl.gmi.model.cvssl.ConstantInteger)value).getValueInt();
        xowl.gmi.model.cvssl.Parameter param = (xowl.gmi.model.cvssl.Parameter)value;
        xowl.lang.owl2.IRI iri = controller.getRepository().getIRI(controller.getOntologyView().getHasIRI().getHasValue() + "#" + param.getName());
        xowl.gmi.model.ast.Decorator decorator = getNearestAST().getDecorator();
        Integer result = (Integer)decorator.getDataValue(iri);
        decorator.addPropertyObserver(iri, obs);
        return result;
    }
    
    protected String getValueString(xowl.gmi.model.cvssl.ValueString value, xowl.interpreter.adapter.DataPropertyObserver obs) {
        if (value == null) return null;
        if (value instanceof xowl.gmi.model.cvssl.ConstantString)
            return ((xowl.gmi.model.cvssl.ConstantString)value).getValueString();
        xowl.gmi.model.cvssl.Parameter param = (xowl.gmi.model.cvssl.Parameter)value;
        xowl.lang.owl2.IRI iri = controller.getRepository().getIRI(controller.getOntologyView().getHasIRI().getHasValue() + "#" + param.getName());
        xowl.gmi.model.ast.Decorator decorator = getNearestAST().getDecorator();
        String result = (String)decorator.getDataValue(iri);
        decorator.addPropertyObserver(iri, obs);
        return result;
    }
    
    protected java.awt.Color getValueColor(xowl.gmi.model.cvssl.ValueColor value, xowl.interpreter.adapter.DataPropertyObserver obs) {
        if (value == null) return null;
        if (value instanceof xowl.gmi.model.cvssl.ConstantColor)
            return new java.awt.Color(((xowl.gmi.model.cvssl.ConstantColor)value).getValueColor());
        xowl.gmi.model.cvssl.Parameter param = (xowl.gmi.model.cvssl.Parameter)value;
        xowl.lang.owl2.IRI iri = controller.getRepository().getIRI(controller.getOntologyView().getHasIRI().getHasValue() + "#" + param.getName());
        xowl.gmi.model.ast.Decorator decorator = getNearestAST().getDecorator();
        Integer result = (Integer)decorator.getDataValue(iri);
        decorator.addPropertyObserver(iri, obs);
        if (result == null) return null;
        return new java.awt.Color(result);
    }
    
    protected void actionAddVariable(xowl.gmi.model.cvssl.Variable var) {
        xowl.lang.owl2.IRI childNode = controller.getRepository().getIRI(controller.getNewNodeIRI());
        xowl.lang.owl2.IRI childSymbol = var.getIRI();
        xowl.lang.owl2.IRI parentNode = getNearestAST().getASTNode().getIRI();
        DiagramUIAction action = new DiagramUIAction(controller.getLocale().diagDropElem);
        action.addInner(controller.getCommandBuilder().create(childNode, childSymbol));
        action.addInner(controller.getCommandBuilder().attach(childSymbol, parentNode, childNode));
        controller.executeUIAction(action);
    }
    protected void actionAddNode(xowl.gmi.model.ast.ASTNode node) {
        DiagramUIAction action = new DiagramUIAction(controller.getLocale().diagDropElem);
        xowl.lang.owl2.IRI childSymbol = node.getSymbol().getIRI();
        xowl.lang.owl2.IRI parentNode = getNearestAST().getASTNode().getIRI();
        xowl.lang.owl2.IRI childNode = node.getIRI();
        action.addInner(controller.getCommandBuilder().attach(childSymbol, parentNode, childNode));
        controller.executeUIAction(action);
    }
    
    public xowl.gmi.view.diagram.GMIAlignment getAlignment(xowl.gmi.model.cvssl.Alignment alignment) {
        if (alignment == null)
            return xowl.gmi.view.diagram.GMIAlignment.Horizontal;
        String[] parts = alignment.getIRIString().split("#");
        String iri = parts[parts.length-1];
        if (iri.equalsIgnoreCase("free"))
            return xowl.gmi.view.diagram.GMIAlignment.Free;
        if (iri.equalsIgnoreCase("top"))
            return xowl.gmi.view.diagram.GMIAlignment.Top;
        if (iri.equalsIgnoreCase("bottom"))
            return xowl.gmi.view.diagram.GMIAlignment.Bottom;
        if (iri.equalsIgnoreCase("left"))
            return xowl.gmi.view.diagram.GMIAlignment.Left;
        if (iri.equalsIgnoreCase("right"))
            return xowl.gmi.view.diagram.GMIAlignment.Right;
        if (iri.equalsIgnoreCase("horizontal"))
            return xowl.gmi.view.diagram.GMIAlignment.Horizontal;
        if (iri.equalsIgnoreCase("vertical"))
            return xowl.gmi.view.diagram.GMIAlignment.Vertical;
        if (iri.equalsIgnoreCase("stackCenter"))
            return xowl.gmi.view.diagram.GMIAlignment.StackCenter;
        if (iri.equalsIgnoreCase("stackLeft"))
            return xowl.gmi.view.diagram.GMIAlignment.StackLeft;
        if (iri.equalsIgnoreCase("stackRight"))
            return xowl.gmi.view.diagram.GMIAlignment.StackRight;
        if (iri.equalsIgnoreCase("stackTop"))
            return xowl.gmi.view.diagram.GMIAlignment.StackTop;
        if (iri.equalsIgnoreCase("stackTopLeft"))
            return xowl.gmi.view.diagram.GMIAlignment.StackTopLeft;
        if (iri.equalsIgnoreCase("stackTopRight"))
            return xowl.gmi.view.diagram.GMIAlignment.StackTopRight;
        if (iri.equalsIgnoreCase("stackBottom"))
            return xowl.gmi.view.diagram.GMIAlignment.StackBottom;
        if (iri.equalsIgnoreCase("stackBottomLeft"))
            return xowl.gmi.view.diagram.GMIAlignment.StackBottomLeft;
        if (iri.equalsIgnoreCase("stackBottomRight"))
            return xowl.gmi.view.diagram.GMIAlignment.StackBottomRight;
        return xowl.gmi.view.diagram.GMIAlignment.Horizontal;
    }
    
    protected int getFontStyle(xowl.gmi.model.cvssl.Font font) {
        int result = java.awt.Font.PLAIN;
        for (xowl.gmi.model.cvssl.FontStyle style : font.getAllFontStyles()) {
            String iri = style.getIRIString();
            if (iri.endsWith("italic")) result = result | java.awt.Font.ITALIC;
            if (iri.endsWith("bold")) result = result | java.awt.Font.BOLD;
        }
        return result;
    }
}
